﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Infusion.CRM.WF.CRM40WSX.BarcodeSvc;
using System.IO;

namespace Infusion.CRM.WF.CRM40WSX.Proxy
{
    /// <summary>
    /// Proxy for BarCodeSvc service
    /// </summary>
    public class BarcodeProxy
    {

        #region Types

        /// <summary>
        /// Image format (output)
        /// </summary>
        public enum BpImageFormat
        {
            BMP,
            EMF,
            EXIF,
            GIF,
            ICON,
            JPEG,
            MemoryBMP,
            PNG,
            TIFF,
            WMF,
        }

        /// <summary>
        /// Barcode Options
        /// </summary>
        public enum BpBarcodeOption
        {
            /// <summary>
            /// Only barcode
            /// </summary>
            None,

            /// <summary>
            /// Barcode + Text
            /// </summary>
            Code,

            /// <summary>
            /// Only barcode
            /// </summary>
            Typ,

            /// <summary>
            /// Barcode + Text
            /// </summary>
            Both
        }

        /// <summary>
        /// Barcode Type
        /// </summary>
        public enum BpBarcodeType
        {
            Code_2_5_interleaved,
            Code_2_5_industrial,
            Code_2_5_matrix,
            Code39,
            Code39Extended,
            Code128A,
            Code128B,
            Code128C,
            Code93,
            Code93Extended,
            CodeMSI,
            CodePostNet,
            CodeCodabar,
            CodeEAN8,
            CodeEAN13,
            CodeUPC_A,
            CodeUPC_E0,
            CodeUPC_E1,
            CodeUPC_Supp2,
            CodeUPC_Supp5,
            CodeEAN128A,
            CodeEAN128B,
            CodeEAN128C
        }

        /// <summary>
        /// Checksum Method
        /// </summary>
        public enum BpCheckSumMethod
        {
            None,
            Modulo10
        }

        /// <summary>
        /// Position of text
        /// </summary>
        public enum BpTextPosition
        {
            TopLeft,
            TopRight,
            TopCenter,
            BottomLeft,
            BottomRight,
            BottomCenter
        }

        #endregion

        #region Properties

        /// <summary>
        /// Angle of the barcode section measured in degrees counterclockwise
        /// </summary>
        public int Angle { get; set; }

        /// <summary>
        /// Choose between various image formats (default: GIF)
        /// </summary>
        public BpImageFormat ImageFormat { get; set; }

        /// <summary>
        /// Barcode Options (default: Both)
        /// </summary>
        public BpBarcodeOption Option { get; set; }

        /// <summary>
        /// Barcode Type (default: Code39Extended)
        /// </summary>
        public BpBarcodeType Type { get; set; }

        /// <summary>
        /// Barcode Checksum (default: true)
        /// </summary>
        public bool CheckSum { get; set; }

        /// <summary>
        /// Checksum Method (default: Modulo10)
        /// </summary>
        public BpCheckSumMethod CheckSumMethod { get; set; }

        /// <summary>
        /// Font Family
        /// </summary>
        public string FontName { get; set; }

        /// <summary>
        /// Font Size (default: 20)
        /// </summary>
        public float FontSize { get; set; }

        /// <summary>
        /// Barcode Height in pixels (default: 200)
        /// </summary>
        public int Height { get; set; }

        /// <summary>
        /// Barcode Width in pixels (default: 400)
        /// </summary>
        public int Width { get; set; }

        /// <summary>
        /// Position of text (default: BottomCenter)
        /// </summary>
        public BpTextPosition TextPosition { get; set; }

        /// <summary>
        /// Left offset in pixels
        /// </summary>
        public int LeftOffset { get; set; }

        /// <summary>
        /// Top offset in pixels
        /// </summary>
        public int TopOffset { get; set; }

        /// <summary>
        /// Module (multiplier for line width; 1 means use 1 pixel for thinnest bar; default: 4)
        /// </summary>
        public int Module { get; set; }

        /// <summary>
        /// Barcode Ratio (ratio between thin and thick bars; default: 2)
        /// </summary>
        public int Ratio { get; set; }

        #endregion

        /// <summary>
        /// Default Constructor
        /// </summary>
        public BarcodeProxy()
        {
            this.Option = BpBarcodeOption.Both;
            this.Type = BpBarcodeType.Code39Extended;
            this.CheckSum = true;
            this.CheckSumMethod = BpCheckSumMethod.Modulo10;
            this.FontSize = 20;
            this.Width = 400;
            this.Height = 200;
            this.TextPosition = BpTextPosition.BottomCenter;
            this.Module = 4;
            this.Ratio = 2;
        }

        /// <summary>
        /// Generate barcode image
        /// </summary>
        /// <param name="text">Numeric value representing the code</param>
        /// <returns>Binary array represeting the image.</returns>
        public byte[] GenerateBarCode(string text)
        {
            BarCodeData bd = new BarCodeData();

            bd.BarCodeImageFormat = (ImageFormats)Enum.Parse(typeof(ImageFormats), this.ImageFormat.ToString());
            bd.barcodeOption = (BarcodeOption)Enum.Parse(typeof(BarcodeOption), this.Option.ToString());
            bd.barcodeType = (BarcodeType)Enum.Parse(typeof(BarcodeType), this.Type.ToString());
            bd.checkSumMethod = (CheckSumMethod)Enum.Parse(typeof(CheckSumMethod), this.CheckSumMethod.ToString());
            bd.showTextPosition = (ShowTextPosition)Enum.Parse(typeof(ShowTextPosition), this.TextPosition.ToString());
            bd.Angle = this.Angle;
            bd.CheckSum = this.CheckSum;
            bd.FontName = this.FontName;
            bd.FontSize = this.FontSize;
            bd.Height = this.Height;
            bd.Width = this.Width;
            bd.Left = this.LeftOffset;
            bd.Top = this.TopOffset;
            bd.Module = this.Module;
            bd.Ratio = this.Ratio;

            return new BarcodeSvc.BarCode().GenerateBarCode(bd, text);
        }

        /// <summary>
        /// Save barcode image
        /// </summary>
        /// <param name="image">Binary array representing the image.</param>
        /// <param name="fileName">Output file name</param>
        public void GenerateImageFile(byte[] image, string fileName)
        {
            BinaryWriter binWriter = new BinaryWriter(new FileStream(fileName, FileMode.Create));
            binWriter.Write(image);
            binWriter.Close();
        }

        /// <summary>
        /// Save barcode image
        /// </summary>
        /// <param name="fmt">File format</param>
        /// <param name="text">Numeric value representing the code</param>
        /// <param name="fileName">Output file name</param>
        public void GenerateImageFile(BarcodeProxy.BpImageFormat fmt, string text, string fileName)
        {
            this.ImageFormat = fmt;
            byte[] array = this.GenerateBarCode(text);
            this.GenerateImageFile(array, fileName);
        }

    }
}
